<template>
  <div class="system-bg">
    <el-card class="user-card" shadow="hover">
      <div slot="header" class="card-header-vertical">
        <div class="header-title">用户管理</div>
        <div class="header-btn-group right">
          <el-button class="add-btn" type="primary" @click="onShowAdd">
            <i class="el-icon-plus"></i> 新增用户
          </el-button>
          <el-button class="aux-btn" :disabled="multipleSelection.length !== 1" @click="setRolesBatch">
            <i class="el-icon-s-custom"></i> 分配角色
          </el-button>
          <el-button class="aux-btn" :disabled="!multipleSelection.length" @click="batchRemove">
            <i class="el-icon-delete"></i> 批量删除
          </el-button>
          <el-button class="aux-btn" :disabled="multipleSelection.length !== 1" @click="resetPwdBatch">
            <i class="el-icon-refresh"></i> 重置密码
          </el-button>
        </div>
      </div>
      <el-form :inline="true" :model="searchForm" class="search-bar">
        <el-form-item label="用户名">
          <el-input v-model="searchForm.username" placeholder="用户名" size="small" />
        </el-form-item>
        <el-form-item label="类型">
          <el-select v-model="searchForm.userType" placeholder="全部" size="small">
            <el-option label="全部" :value="''" />
            <el-option label="后台用户" value="admin" />
            <el-option label="小程序用户" value="miniapp" />
          </el-select>
        </el-form-item>
        <el-form-item>
          <el-button type="primary" size="small" @click="onSearch">搜索</el-button>
        </el-form-item>
        <el-form-item>
          <el-button size="small" @click="onReset">重置</el-button>
        </el-form-item>
      </el-form>
      <el-table
        ref="userTable"
        :data="list"
        style="width:100%"
        class="user-table"
        highlight-current-row
        @selection-change="handleSelectionChange"
        @row-click="handleRowClick"
      >
        <el-table-column type="selection" width="50" />
        <el-table-column prop="id" label="ID" width="70" align="center" />
        <el-table-column prop="username" label="用户名" width="120" />
        <el-table-column prop="nickname" label="昵称" width="120" />
        <el-table-column prop="userType" label="类型" width="100">
          <template slot-scope="scope">
            <el-tag :type="scope.row.userType === 'admin' ? 'primary' : 'success'">
              {{ scope.row.userType === 'admin' ? '后台用户' : '小程序用户' }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column prop="clanId" label="家族" width="120">
          <template slot-scope="scope">
            <span>{{ getClanName(scope.row.clanId) }}</span>
          </template>
        </el-table-column>
        <el-table-column prop="branchId" label="分支" width="120">
          <template slot-scope="scope">
            <span>{{ getBranchName(scope.row.branchId) }}</span>
          </template>
        </el-table-column>
        <el-table-column label="角色" width="120">
          <template slot-scope="scope">
            <span v-if="Array.isArray(scope.row.roles) && scope.row.roles.length">
              <el-tag v-for="role in scope.row.roles" :key="role" size="mini" style="margin-right:2px;">{{ role }}</el-tag>
            </span>
            <span v-else>-</span>
          </template>
        </el-table-column>
        <el-table-column prop="status" label="状态" width="90">
          <template slot-scope="scope">
            <el-tag :type="scope.row.status === 1 ? 'success' : 'danger'">
              {{ scope.row.status === 1 ? '启用' : '禁用' }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column prop="lastLogin" label="最后登录" width="160" />
        <el-table-column prop="createdAt" label="创建时间" width="160" />
        <el-table-column label="操作" width="220" align="center">
          <template slot-scope="scope">
            <div style="display: flex; flex-direction: row; justify-content: center; align-items: center; gap: 8px;">
              <el-button size="mini" class="edit-btn" @click="editWithTip(scope.row)">编辑</el-button>
              <el-button size="mini" class="delete-btn" type="danger" @click="removeWithTip(scope.row)">删除</el-button>
            </div>
          </template>
        </el-table-column>
      </el-table>
      <el-pagination
        :total="total"
        :page-size="size"
        :current-page="current"
        @current-change="load"
        @size-change="handleSizeChange"
        layout="total, prev, pager, next, jumper, ->, sizes"
        :page-sizes="[10, 20, 50, 100]"
        class="user-pagination"
      />
    </el-card>
    
    <!-- 新增/编辑用户弹窗 -->
    <el-dialog :visible.sync="showDialog" :title="dialogTitle" class="fade-dialog custom-dialog" :close-on-click-modal="false" width="500px">
      <el-form :model="form" :rules="rules" ref="userForm" label-width="90px" class="dialog-form">
        <el-form-item label="用户名" prop="username">
          <el-input v-model="form.username" :disabled="isEdit" />
        </el-form-item>
        <el-form-item label="昵称" prop="nickname">
          <el-input v-model="form.nickname" />
        </el-form-item>
        <el-form-item label="用户类型" prop="userType">
          <el-select v-model="form.userType" placeholder="请选择用户类型" style="width: 100%;">
            <el-option label="后台用户" value="admin" />
            <el-option label="小程序用户" value="miniapp" />
          </el-select>
        </el-form-item>
        <el-form-item label="家族" prop="clanId">
          <el-select v-model="form.clanId" placeholder="请选择家族" style="width: 100%;" @change="onClanChange">
            <el-option v-for="clan in clanList" :key="clan.id" :label="clan.name" :value="clan.id" />
          </el-select>
        </el-form-item>
        <el-form-item label="分支" prop="branchId">
          <el-select v-model="form.branchId" placeholder="请选择分支" style="width: 100%;">
            <el-option v-for="branch in branchList" :key="branch.id" :label="branch.name" :value="branch.id" />
          </el-select>
        </el-form-item>
        <el-form-item label="角色" prop="roleIds" v-if="!isEdit">
          <el-select v-model="form.roleIds" multiple placeholder="请选择角色" style="width: 100%;">
            <el-option v-for="role in roleList" :key="role.id" :label="role.name" :value="role.id" />
          </el-select>
        </el-form-item>
        <el-form-item label="密码" v-if="!isEdit" prop="password">
          <el-input v-model="form.password" type="password" />
        </el-form-item>
        <el-form-item label="状态" prop="status">
          <el-select v-model="form.status" placeholder="请选择状态" style="width: 100%;">
            <el-option label="启用" :value="1" />
            <el-option label="禁用" :value="0" />
          </el-select>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="showDialog=false">取消</el-button>
        <el-button type="primary" @click="save">确定</el-button>
      </div>
    </el-dialog>
    
    <!-- 设置角色弹窗 -->
    <el-dialog :visible.sync="showRoleDialog" title="设置用户角色" class="fade-dialog custom-dialog" :close-on-click-modal="false" width="400px">
      <el-form label-width="90px">
        <el-form-item label="用户">
          <span>{{ currentUser ? currentUser.username : '' }}</span>
        </el-form-item>
        <el-form-item label="角色">
          <el-checkbox-group v-model="selectedRoles">
            <el-checkbox
              v-for="role in roleList"
              :key="role.id"
              :label="role.id"
            >
              {{ role.name }}
            </el-checkbox>
          </el-checkbox-group>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="showRoleDialog=false">取消</el-button>
        <el-button type="primary" @click="saveRoles">确定</el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import { getUserList, addUser, updateUser, deleteUser, getUserRoles, setUserRoles } from '@/api/user';
import { getRoleList } from '@/api/role';
import { getClanList } from '@/api/clan';
import { getBranchList } from '@/api/branch';

export default {
  name: 'SystemUser',
  data() {
    return {
      list: [],
      total: 0,
      size: 10,
      current: 1,
      showDialog: false,
      showRoleDialog: false,
      isEdit: false,
      dialogTitle: '新增用户',
      form: {
        username: '',
        nickname: '',
        userType: 'admin',
        password: '',
        status: 1,
        roleIds: [],
        clanId: null,
        branchId: null
      },
      roleList: [],
      selectedRoles: [],
      currentUser: null,
      searchForm: {
        username: '',
        nickname: '',
        status: '',
        userType: ''
      },
      multipleSelection: [],
      rules: {
        username: [
          { required: true, message: '请输入用户名', trigger: 'blur' }
        ],
        nickname: [
          { required: true, message: '请输入昵称', trigger: 'blur' }
        ],
        userType: [
          { required: true, message: '请选择用户类型', trigger: 'change' }
        ],
        status: [
          { required: true, message: '请选择状态', trigger: 'change' }
        ],
        password: [
          { required: true, message: '请输入密码', trigger: 'blur' }
        ],
        roleIds: [
          { required: true, type: 'array', min: 1, message: '请选择角色', trigger: 'change' }
        ]
      },
      clanList: [],
      branchList: []
    };
  },
  created() {
    this.load();
    this.loadRoles();
    this.loadClans();
  },
  methods: {
    async load(page = 1) {
      this.current = page;
      const params = {
        page,
        size: this.size,
        ...this.searchForm
      };
      const data = await getUserList(params);
      this.list = data.records;
      this.total = data.total;
      this.size = data.size;
      this.current = data.current;
    },
    handleSizeChange(size) {
      this.size = size;
      this.load(1);
    },
    async loadClans() {
      try {
        const data = await getClanList({ page: 1, size: 1000 });
        this.clanList = data.records || [];
      } catch (error) {
        console.error('加载家族列表失败:', error);
        this.$message.error('加载家族列表失败');
      }
    },
    async loadBranches(clanId) {
      if (!clanId) {
        this.branchList = [];
        return;
      }
      try {
        const data = await getBranchList({ page: 1, size: 1000, clanId });
        this.branchList = data.records || [];
      } catch (error) {
        console.error('加载分支列表失败:', error);
        this.$message.error('加载分支列表失败');
      }
    },
    async loadRoles() {
      try {
        const data = await getRoleList({ page: 1, size: 1000 });
        this.roleList = data.records || [];
      } catch (error) {
        console.error('加载角色列表失败:', error);
        this.$message.error('加载角色列表失败');
      }
    },
    onClanChange(clanId) {
      this.form.branchId = null;
      if (clanId) {
        this.loadBranches(clanId);
      } else {
        this.branchList = [];
      }
    },
    getClanName(clanId) {
      const clan = this.clanList.find(c => c.id === clanId);
      return clan ? clan.name : '-';
    },
    getBranchName(branchId) {
      const branch = this.branchList.find(b => b.id === branchId);
      return branch ? branch.name : '-';
    },
    onShowAdd() {
      this.isEdit = false;
      this.dialogTitle = '新增用户';
      this.form = {
        username: '',
        nickname: '',
        userType: 'admin',
        password: '',
        status: 1,
        roleIds: [],
        clanId: null,
        branchId: null
      };
      this.branchList = [];
      this.showDialog = true;
    },
    edit(row) {
      this.isEdit = true;
      this.dialogTitle = '编辑用户';
      this.form = { ...row };
      this.loadBranches(row.clanId);
      this.showDialog = true;
    },
    async save() {
      this.$refs.userForm.validate(async valid => {
        if (!valid) return;
        try {
          if (this.isEdit) {
            await updateUser(this.form.id, this.form);
            this.$message.success('用户更新成功');
          } else {
            const { roleIds, ...userData } = this.form;
            await addUser({ ...userData, roleIds });
            this.$message.success('用户添加成功');
          }
          this.showDialog = false;
          this.load();
        } catch (error) {
          console.error('保存用户失败:', error);
          this.$message.error('保存用户失败');
        }
      });
    },
    async remove(row) {
      try {
        await this.$confirm('确定要删除该用户吗？', '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        });
        await deleteUser(row.id);
        this.$message.success('用户删除成功');
        this.load();
      } catch (error) {
        if (error !== 'cancel') {
          console.error('删除用户失败:', error);
          this.$message.error('删除用户失败');
        }
      }
    },
    async setRoles(row) {
      this.currentUser = row;
      this.selectedRoles = [];
      try {
        const roles = await getUserRoles(row.id);
        this.selectedRoles = roles.map(role => role.id);
        this.showRoleDialog = true;
      } catch (error) {
        console.error('获取用户角色失败:', error);
        this.$message.error('获取用户角色失败');
      }
    },
    async saveRoles() {
      try {
        await setUserRoles(this.currentUser.id, this.selectedRoles);
        this.$message.success('角色设置成功');
        this.showRoleDialog = false;
        this.load();
      } catch (error) {
        console.error('设置用户角色失败:', error);
        this.$message.error('设置用户角色失败');
      }
    },
    onSearch() {
      this.current = 1; // 搜索时重置当前页为1
      this.load();
    },
    onReset() {
      this.searchForm = {
        username: '',
        nickname: '',
        status: '',
        userType: ''
      };
      this.load();
    },
    handleSelectionChange(val) {
      this.multipleSelection = val;
    },
    handleRowClick(row) {
      this.$refs.userTable.clearSelection();
      this.$refs.userTable.toggleRowSelection(row, true);
    },
    async batchRemove() {
      if (!this.multipleSelection.length) {
        this.$message.warning('请选择要删除的用户');
        return;
      }
      try {
        await this.$confirm('确定要批量删除选中的用户吗？', '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        });
        await Promise.all(this.multipleSelection.map(user => deleteUser(user.id)));
        this.$message.success('批量删除成功');
        this.load();
      } catch (error) {
        if (error !== 'cancel') {
          console.error('批量删除失败:', error);
          this.$message.error('批量删除失败');
        }
      }
    },
    async exportUsers() {
      try {
        const params = {
          ...this.searchForm,
          page: 1,
          size: this.total // 导出所有数据
        };
        const response = await getUserList(params);
        const data = response.records;
        const headers = ['ID', '用户名', '昵称', '类型', '角色', '状态', '最后登录', '创建时间'];
        const filename = `用户列表_${new Date().toISOString().slice(0, 10)}.xlsx`;
        this.$utils.exportExcel(data, headers, filename);
        this.$message.success('用户列表导出成功');
      } catch (error) {
        console.error('导出用户列表失败:', error);
        this.$message.error('导出用户列表失败');
      }
    },
    async resetPwd(row) {
      try {
        await this.$confirm(`确定要重置用户 "${row.username}" 的密码吗？`, '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        });
        await updateUser(row.id, { password: '123456' }); // 示例密码
        this.$message.success('密码重置成功');
        this.load();
      } catch (error) {
        if (error !== 'cancel') {
          console.error('重置密码失败:', error);
          this.$message.error('重置密码失败');
        }
      }
    },
    async resetPwdBatch() {
      if (this.multipleSelection.length !== 1) {
        this.$message.warning('请选择一条用户进行密码重置');
        return;
      }
      const row = this.multipleSelection[0];
      try {
        await this.$confirm(`确定要重置用户 "${row.username}" 的密码吗？`, '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        });
        await updateUser(row.id, { password: '123456' });
        this.$message.success('密码重置成功，初始密码为123456');
        this.load();
      } catch (error) {
        if (error !== 'cancel') {
          console.error('重置密码失败:', error);
          this.$message.error('重置密码失败');
        }
      }
    },
    editWithTip(row) {
      this.$message.info('正在进入编辑用户界面');
      this.edit(row);
    },
    setRolesWithTip(row) {
      this.$message.info('正在进入分配角色界面');
      this.setRoles(row);
    },
    async removeWithTip(row) {
      try {
        await this.$confirm('确定要删除该用户吗？', '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        });
        await deleteUser(row.id);
        this.$message.success('用户删除成功');
        this.load();
      } catch (error) {
        if (error !== 'cancel') {
          console.error('删除用户失败:', error);
          this.$message.error('删除用户失败');
        }
      }
    },
    async setRolesBatch() {
      if (this.multipleSelection.length !== 1) {
        this.$message.warning('请选择一条用户进行角色分配');
        return;
      }
      this.setRolesWithTip(this.multipleSelection[0]);
    }
  }
};
</script>

<style scoped>
.system-bg {
  min-height: 80vh;
  background: linear-gradient(135deg, #f4f6fa 60%, #e0e7ff 100%);
  display: flex;
  align-items: flex-start;
  justify-content: center;
  padding: 48px 0;
  animation: fadeIn 0.8s;
}
@keyframes fadeIn {
  from { opacity: 0; transform: translateY(30px);}
  to { opacity: 1; transform: none;}
}
.user-card {
  width: 1100px;
  border-radius: 18px;
  box-shadow: 0 8px 32px 0 rgba(31, 38, 135, 0.10);
  background: rgba(255,255,255,0.95);
  transition: box-shadow 0.3s;
}
.card-header-vertical {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  padding-bottom: 8px;
}
.header-title {
  font-size: 22px;
  font-weight: bold;
  margin-bottom: 10px;
  text-align: left;
}
.header-btn-group {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  background: none;
  border-radius: 0;
  padding: 0;
  box-shadow: none;
}
.header-btn-group.right {
  justify-content: flex-end;
}
.header-btn-group .el-button {
  margin-right: 8px;
  height: 34px;
  font-size: 15px;
  padding: 0 18px;
  display: flex;
  align-items: center;
}
.header-btn-group .el-button:last-child {
  margin-right: 0;
}
.add-btn {
  background: linear-gradient(90deg, #6a82fb 0%, #fc5c7d 100%);
  border: none;
  color: #fff;
  font-weight: bold;
}
.add-btn:hover {
  background: linear-gradient(90deg, #fc5c7d 0%, #6a82fb 100%);
}
.aux-btn {
  background: #fff;
  border: 1px solid #e4e7ed;
  color: #606266;
  font-weight: 500;
  transition: all 0.2s;
}
.aux-btn:disabled {
  color: #ccc;
  border-color: #eee;
  background: #f8f8f8;
}
.aux-btn:hover {
  border-color: #409EFF;
  color: #409EFF;
  background: #f4faff;
}
.header-btn-group .el-icon-plus,
.header-btn-group .el-icon-delete,
.header-btn-group .el-icon-download {
  font-size: 16px;
  margin-right: 4px;
}
.user-table {
  border-radius: 10px;
  overflow: hidden;
  margin-bottom: 18px;
}
.user-table ::v-deep .el-table__row:hover {
  background: #f0f7ff !important;
  transition: background 0.2s;
}
.edit-btn {
  background: #fff;
  border: 1px solid #6a82fb;
  color: #6a82fb;
  margin-right: 8px;
  transition: all 0.2s;
}
.edit-btn:hover {
  background: #6a82fb;
  color: #fff;
}
.delete-btn {
  background: #fff;
  border: 1px solid #fc5c7d;
  color: #fc5c7d;
  transition: all 0.2s;
}
.delete-btn:hover {
  background: #fc5c7d;
  color: #fff;
}
.user-pagination {
  margin-top: 18px;
  text-align: right;
}
.user-pagination ::v-deep .el-pager li {
  border-radius: 6px;
  transition: background 0.2s;
}
.user-pagination ::v-deep .el-pager li.active {
  background: #6a82fb;
  color: #fff;
}
.fade-dialog ::v-deep .el-dialog__wrapper {
  animation: fadeIn 0.4s;
}
.custom-dialog ::v-deep .el-dialog {
  border-radius: 16px;
  box-shadow: 0 8px 32px 0 rgba(31, 38, 135, 0.18);
  background: #fafdff;
  padding-bottom: 0;
}
.dialog-form {
  padding: 12px 0 0 0;
}
.dialog-form ::v-deep .el-form-item {
  margin-bottom: 22px;
}
.dialog-footer {
  text-align: right;
  padding: 8px 0 8px 0;
}
.dialog-footer .el-button {
  min-width: 80px;
  border-radius: 6px;
  font-weight: 500;
  margin-left: 8px;
}
.dialog-footer .el-button--primary {
  background: linear-gradient(90deg, #6a82fb 0%, #fc5c7d 100%);
  border: none;
}
.dialog-footer .el-button--primary:hover {
  background: linear-gradient(90deg, #fc5c7d 0%, #6a82fb 100%);
}
.search-bar {
  margin-bottom: 20px;
  padding: 20px;
  background: transparent;
  border-radius: 8px;
  border: none;
}
</style> 